package hn.sigit.logic.bpm.actionhandler;

import java.util.Date;

import hn.sigit.dao.hnd.administrative.HND_TransactionDAO;
import hn.sigit.dao.hnd.administrative.HND_TransactionLogDAO;
import hn.sigit.dao.hnd.administrative.HND_UserDAO;
import hn.sigit.logic.ladmshadow.Util;
import hn.sigit.model.hnd.administrative.HND_ActivityType;
import hn.sigit.model.hnd.administrative.HND_Transaction;
import hn.sigit.model.hnd.administrative.HND_TransactionLog;
import hn.sigit.model.hnd.administrative.HND_User;

import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.def.Event;
import org.jbpm.graph.exe.ExecutionContext;


public class TransactionHandler implements ActionHandler {
	private static final long serialVersionUID = 1L;
	
	private String transitionMessage;
	
	
	@Override
	public void execute(ExecutionContext executionContext) throws Exception {
		long presentationId = Long.parseLong(executionContext.getProcessInstance().getKey());
		HND_Transaction hndTrx = HND_TransactionDAO.loadRequestByPresentationId(presentationId);
		HND_TransactionLog hndTrxLog = null;

		Event event = executionContext.getEvent();
		if (event.getEventType().equals(Event.EVENTTYPE_NODE_ENTER)) {
			hndTrxLog = new HND_TransactionLog();
			hndTrxLog.setTransaction(hndTrx);
			//Update current activity when entering a new node
			String strActivity = executionContext.getNode().getName();
			HND_ActivityType activityType = stringToActivityType(strActivity);
			
			hndTrx.setCurrentActivity(activityType);
			hndTrxLog.setDateActivity(new Date());
			hndTrxLog.setActivity(activityType);
			hndTrxLog.setTransitionMessage(transitionMessage);
			//Update current actor since the task might change its actor when transitioning
			assignCurrentActor(hndTrx, hndTrxLog, executionContext);
			
			switch (activityType) {
			case ANALYSIS:
				//Always delete the presentation shadow records when entering the Analysis step
				Util.deletePresentationShadow(presentationId, true);
				break;
			case END:
				//End the process when reaching the end state
				executionContext.getProcessInstance().end();
				break;
			}
			
			
		}
		else if (event.getEventType().equals(Event.EVENTTYPE_NODE_LEAVE)) {
			//TODO: Registrar Fecha de Finalizacion en el transaction log
		}
		else if (event.getEventType().equals(Event.EVENTTYPE_TASK_ASSIGN)) {
			hndTrxLog = HND_TransactionLogDAO.loadLastTransactionLogByPresentationId(presentationId);
			//Update current actor since the task is being assigned
			assignCurrentActor(hndTrx, hndTrxLog, executionContext);
		}
		
		HND_TransactionDAO.save(hndTrx);
		if (hndTrxLog != null)
			HND_TransactionLogDAO.save(hndTrxLog);
	}
	
	public String getTransitionMessage() {
		return transitionMessage;
	}
	public void setTransitionMessage(String transitionMessage) {
		this.transitionMessage = transitionMessage;
	}


	private void assignCurrentActor(HND_Transaction hndTrx, HND_TransactionLog hndTrxLog,
			ExecutionContext executionContext) {
		//TODO: more testing with auto assigning actors
		if (executionContext.getTaskInstance() != null) {
			String actor = executionContext.getTaskInstance().getActorId();
			HND_User hndUser = HND_UserDAO.loadUser(actor);
			
			hndTrx.setCurrentActorUserName(hndUser.getUserName());
			hndTrxLog.setDateClaimed(new Date());
			hndTrxLog.setClaimingUser(hndUser);
			//TODO: fill the full user name field
		}
		else
			hndTrx.setCurrentActorUserName(null);
	}
	
	private HND_ActivityType stringToActivityType(String strActivity) {
		HND_ActivityType activityType = HND_ActivityType.valueOf(strActivity.toUpperCase());
		return activityType;
	}

}
